package com.dingreading.cloud.admin.controller;

import com.alibaba.excel.EasyExcel;
import com.dingreading.cloud.admin.dto.CmorderDto;
import com.dingreading.cloud.admin.dto.CmservicesDto;
import com.dingreading.cloud.admin.dto.ProjectInfoDto;
import com.dingreading.cloud.admin.dto.vo.MemberAndCmorderVO;
import com.dingreading.cloud.admin.dto.vo.MemberAndCmorderVOV2;
import com.dingreading.cloud.admin.dto.vo.MemberServiceVo;
import com.dingreading.cloud.admin.dto.vo.MemberVO;
import com.dingreading.cloud.admin.entity.*;
import com.dingreading.cloud.admin.service.*;
import com.dingreading.cloud.admin.util.ScheduleUtil;
import com.dingreading.cloud.admin.util.UidUtil;
import com.dingreading.cloud.admin.util.bean.CmorderUtil;
import com.dingreading.cloud.admin.util.bean.MemberUtil;
import com.dingreading.cloud.admin.util.redis.RedisService;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.*;
import com.dingreading.cloud.common.util.excel.ExcelHandler;
import com.google.common.collect.Lists;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/system/members")
@Api(tags = "总部-门店会员管理")
public class MemberController {

    @Resource
    protected MembersService membersService;
    @Resource
    protected CmservicesService cmservicesService;
    @Resource
    protected StaffService staffService;
    @Resource
    protected StoreProjectsService storeProjectsService;
    @Resource
    protected CmordersService cmordersService;
    @Resource
    protected StoresService storesService;
    @Resource
    protected MemberFollowService memberFollowService;
    @Resource
    protected RedisService redisService;

    private final List<String> storeUidList = Arrays.asList(
            AccountUtil.WKLS_UID, AccountUtil.QHY_UID, AccountUtil.LHY_UID, AccountUtil.SXMD_UID,
            AccountUtil.SJGG_UID, AccountUtil.SSMG_UID, AccountUtil.WHDD_UID, AccountUtil.BLXB_UID,
            AccountUtil.LHTJ_UID, AccountUtil.SMLT_UID, AccountUtil.BHYT_UID, AccountUtil.WHC_UID,
            AccountUtil.ASMG_UID
    );


    @ApiOperation(value = "分页列表")
    @PostMapping(value = "/pageList")
    public R<Object> pageList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "姓名/手机号") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid", required = false) String storeUid
    ) {
        Page<Members> page = this.membersService.pageList(pageUtil, keyword, storeUid);

        PageBeanDto dto = new PageBeanDto();
        dto.setList(page.getRecords());
        dto.setTotal(page.getTotalRow());
        return R.ok(dto);
    }

    @ApiOperation(value = "未续费会员")
    @PostMapping(value = "/exportList", produces = "application/vnd.ms-excel;charset=UTF-8")
    public void exportList(
            HttpServletResponse response,
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "开始日期 yyyy-MM-dd") @RequestParam(value = "beginDate") String beginDate,
            @ApiParam(value = "结束日期 yyyy-MM-dd") @RequestParam(value = "endDate") String endDate
    ) throws Exception {
        // 默认获取本月的第一天和最后一天
        if (StringUtils.isBlank(beginDate) || StringUtils.isBlank(endDate)) {
            Date monthMinDate = DateUtil.getMonthMinDate();
            Date monthMaxDate = DateUtil.getMonthMaxDate();
            beginDate = DateUtil.getDefaultTime2DateStr(monthMinDate);
            endDate = DateUtil.getDefaultTime2DateStr(monthMaxDate);
        }

        // 获取已到期的会员服务
        List<Cmservices> list = cmservicesService.overdueListByCorpUidAndStatusAndEndDate(corpUid, beginDate, endDate);
        if (CollectionUtils.isEmpty(list))
            throw new DescribeException("未查询到已到期的会员服务");

        Map<String, List<Cmservices>> map = list.stream().collect(Collectors.groupingBy(Cmservices::getMemberUid, LinkedHashMap::new, Collectors.toList()));

        List<String> memberUids = new ArrayList<>(map.keySet());

        Map<String, List<Cmservices>> validNumMap = cmservicesService.validNumMap(corpUid, endDate, memberUids);

        List<MemberServiceVo> voList = new ArrayList<>();
        for (Map.Entry<String, List<Cmservices>> entry : map.entrySet()) {
            String memberUid = entry.getKey();
            List<Cmservices> value = entry.getValue();
            Cmservices cmservices = value.get(0);
            String storeName = cmservices.getStoreName();
            String memberName = cmservices.getMemberName();

            MemberServiceVo vo = new MemberServiceVo();
            vo.setStoreName(storeName);
            vo.setMemberName(memberName);
            vo.setOverdueInfo(formatInfo(value));

            List<Cmservices> validList = validNumMap.get(memberUid);
            if (CollectionUtils.isNotEmpty(validList)) {
                vo.setValidInfo(formatInfo(validList));
            }

            voList.add(vo);
        }


        String fileName = "未续费会员" + beginDate + "至" + endDate;
        ExcelHandler.exportExcel(response, voList, MemberServiceVo.class, fileName, "未续费会员", true);
    }

    /**
     * 会员服务转文字
     */
    private String formatInfo(List<Cmservices> list) {
        return list.stream().map(dto -> {
                    String msg = "";
                    if (dto.getEndDate() != null) {
                        msg = dto.getProductName() + "-" + DateUtil.getDefaultTime2DateStr(dto.getEndDate());
                    } else {
                        msg = dto.getProductName();
                    }
                    if (dto.getStatus().equals(1))
                        msg += "(已开卡)";
                    if (dto.getStatus().equals(0))
                        msg += "(已暂停)";
                    if (dto.getStatus().equals(-1))
                        msg += "(未开卡)";
                    return msg;
                })
                .collect(Collectors.joining("\n"));
    }

    @ApiOperation(value = "导入会员信息")
    @PostMapping(value = "/importMembers")
    public R<Object> importMembers(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "会员数据excel") @RequestPart(value = "file") MultipartFile file,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName
    ) throws Exception {
        List<MemberVO> voList = ExcelHandler.importExcel(file, MemberVO.class, null);
        if (CollectionUtils.isEmpty(voList))
            return R.fail("不能导入空数据");

        Object store = UidUtil.getStore(storeUid);
        if (store instanceof String) return R.fail(store.toString());
        Stores stores = (Stores) store;
        String corpUid = stores.getCorpUid();
        Long storesId = stores.getId();

        // 添加书籍信息
        for (int i = 0; i < voList.size(); i++) {
            MemberVO vo = voList.get(i);

            String mob = vo.getMob();
            if (StringUtils.isBlank(mob))
                return R.fail("请填写手机号, 第" + (i + 1) + "行");
            if (mob.length() != 11)
                return R.fail("手机号格式错误, 第" + (i + 1) + "行");

            String name = vo.getName();
            if (StringUtils.isBlank(name))
                return R.fail("请填写姓名, 第" + (i + 1) + "行");
            if (name.length() > 100)
                return R.fail("姓名长度超过限制, 第" + (i + 1) + "行");

            String grade = vo.getGrade();
            if (StringUtils.isBlank(grade))
                return R.fail("请填写年级, 第" + (i + 1) + "行");

        }

        List<Members> newMemberList = new ArrayList<>();
        List<String> exMemberList = new ArrayList<>();
        for (int i = 0; i < voList.size(); i++) {
            MemberVO vo = voList.get(i);
            Members exMember = membersService.haveCorpUidAndMobAndFullName(corpUid, vo.getMob(), vo.getName(), null);
            if (null != exMember) {
                exMemberList.add(vo.getMob() + "-" + vo.getName());
                continue;
            }

            String memberUid = KitUtil.getUuid();
            Members member = MemberUtil.createMemberByImport(
                    corpUid, storeUid, storeName, storesId, memberUid, vo.getMob(), vo.getName(), vo.getGrade(),
                    "", null, null
            );
            newMemberList.add(member);
        }
        membersService.saveOrUpdateBatch(newMemberList);

        String msg = "";
        if (CollectionUtils.isNotEmpty(newMemberList))
            msg = "保存会员" + newMemberList.size() + "个";
        if (CollectionUtils.isNotEmpty(exMemberList)) {
            String exMemberStr = exMemberList.stream().collect(Collectors.joining(","));
            msg += "，重复会员:" + exMemberList.size() + "个，" + exMemberStr;
        }

        // 清空门店会员缓存
        redisService.setNullLike(RedisParam.STORE_MEMBERS);

        return R.ok(msg);
    }

    @ApiOperation(value = "导入会员和订单服务")
    @PostMapping(value = "/importMemberAndCmorder")
    public R<Object> importMemberAndCmorder(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "会员数据excel") @RequestPart(value = "file") MultipartFile file,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "门店员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "门店员工名称") @RequestParam(value = "staffName") String staffName
    ) throws Exception {
        List<MemberAndCmorderVO> voList = ExcelHandler.importExcel(file, MemberAndCmorderVO.class, null);
        if (CollectionUtils.isEmpty(voList))
            return R.fail("不能导入空数据");

        Object store = UidUtil.getStore(storeUid);
        if (store instanceof String) return R.fail(store.toString());
        Stores stores = (Stores) store;
        String corpUid = stores.getCorpUid();
        Long storesId = stores.getId();

        Set<String> saleNameList = new HashSet<>();
        Set<String> projectNameList = new HashSet<>();
        // 添加书籍信息
        for (int i = 0; i < voList.size(); i++) {
            MemberAndCmorderVO vo = voList.get(i);

            String mob = vo.getMob();
            if (StringUtils.isBlank(mob))
                return R.fail("请填写手机号, 第" + (i + 1) + "行");
            if (mob.length() != 11)
                return R.fail("手机号格式错误, 第" + (i + 1) + "行");

            String name = vo.getName();
            if (StringUtils.isBlank(name))
                return R.fail("请填写姓名, 第" + (i + 1) + "行");
            if (name.length() > 100)
                return R.fail("姓名长度超过限制, 第" + (i + 1) + "行");

            String grade = vo.getGrade();
            if (StringUtils.isBlank(grade))
                return R.fail("请填写年级, 第" + (i + 1) + "行");

            String projectName = vo.getProjectName();
            if (StringUtils.isBlank(projectName))
                return R.fail("请填写服务名称, 第" + (i + 1) + "行");
            projectNameList.add(projectName);

            Integer lessonNum = vo.getLessonNum();
            if (lessonNum == null || lessonNum <= 0)
                return R.fail("请填写服务次数, 第" + (i + 1) + "行");

            String saleName = vo.getSaleName();
            if (StringUtils.isBlank(saleName))
                return R.fail("请填写签单人, 第" + (i + 1) + "行");
            saleNameList.add(saleName);

            String orderDate = vo.getOrderDate();
            if (StringUtils.isBlank(orderDate))
                return R.fail("请填写收款日期, 第" + (i + 1) + "行");
        }


        // 根据签单人姓名，获取签单人信息
        List<Staff> staffList = staffService.listByCorpUidAndSaleNameIn(Lists.newArrayList(corpUid), saleNameList);
        if (CollectionUtils.isEmpty(staffList))
            return R.fail("签单人信息获取失败");
        Map<String, List<Staff>> staffMap = staffList.stream().collect(Collectors.groupingBy(Staff::getFullName));

        // 根据服务名称，获取服务信息
        List<StoreProjects> storeProjectList = storeProjectsService.listByProjectNameIn(projectNameList);
        if (CollectionUtils.isEmpty(storeProjectList))
            return R.fail("服务信息获取失败");
        Map<String, StoreProjects> projectMap = storeProjectList.stream().collect(Collectors.toMap(StoreProjects::getProjectName, Function.identity()));

        String orderType = EnumType.OrderType.EXP.getType();
        Double orderAmount = 49d;

        List<String> exMemberList = new ArrayList<>();
        List<Members> newMemberList = new ArrayList<>();
        List<Cmorders> newCmorderList = new ArrayList<>();
        List<Cmservices> newCmserviceList = new ArrayList<>();
        for (MemberAndCmorderVO vo : voList) {
            StoreProjects projects = projectMap.get(vo.getProjectName());
            if (projects == null)
                return R.fail("服务项目获取失败");

            String memberUid = "";
            String memberName = "";
            Members exMember = membersService.haveCorpUidAndMobAndFullName(corpUid, vo.getMob(), vo.getName(), null);
            if (null != exMember) {
                // 已有会员账号
                exMemberList.add(vo.getMob() + "-" + vo.getName());

                memberUid = exMember.getUid();
                memberName = exMember.getMemberName();
            } else {
                // 创建会员
                memberUid = KitUtil.getUuid();
                Members member = MemberUtil.createMemberByImport(
                        corpUid, storeUid, storeName, storesId, memberUid, vo.getMob(), vo.getName(), vo.getGrade(),
                        "", staffUid, staffName
                );
                memberName = member.getMemberName();
                newMemberList.add(member);
            }

            String saleStaffUid = "";
            String saleStaffFullName = "";
            String saleStaffPriPhone = "";
            String saleStaffPubPhone = "";
            String saleStaffNickName = "";
            List<Staff> saleStaffList = staffMap.get(vo.getSaleName());
            if (CollectionUtils.isNotEmpty(saleStaffList)) {
                Staff saleStaff = saleStaffList.get(0);
                saleStaffUid = saleStaff.getUid();
                saleStaffFullName = saleStaff.getFullName();
                saleStaffPriPhone = saleStaff.getPriPhone();
                saleStaffPubPhone = saleStaff.getPubPhone();
                saleStaffNickName = saleStaff.getNickName();
            }

            Date orderDateValue = null;
            if (StringUtils.isNotBlank(vo.getOrderDate()))
                orderDateValue = DateUtil.parseDate(vo.getOrderDate());

            // 创建订单信息
            Cmorders cmorders = CmorderUtil.newCmorder(
                    null, corpUid, storeUid, storeName, staffUid, staffName, memberUid, memberName,
                    saleStaffUid, saleStaffFullName, saleStaffPriPhone, saleStaffPubPhone, saleStaffNickName,
                    null, orderType, orderAmount, orderDateValue,
                    "0", null, vo.getRemark(), null, 2, ""
            );
            newCmorderList.add(cmorders);

            // 服务次数
            int lessonNum = NepUtil.nullToZero(vo.getLessonNum());
            // 服务天数
            int serviceDays = 31;
            if (lessonNum > 4)
                serviceDays = 62;

            // 创建服务信息
            Cmservices cmservices = CmorderUtil.newImportService(
                    corpUid, storeUid, storeName,
                    memberUid, memberName, staffUid, staffName,
                    cmorders.getOrderCode(), orderType, vo.getLessonNum(), serviceDays, 0,
                    20L, ScheduleUtil.TIYAN_UID, "体验课", projects.getLessonStatus(), projects.getFreeStatus()
            );
            // 默认添加好读服务
            Cmservices haoduService = CmorderUtil.newImportService(
                    corpUid, storeUid, storeName,
                    memberUid, memberName, staffUid, staffName,
                    cmorders.getOrderCode(), orderType, null, 31, 0,
                    2L, ScheduleUtil.HAODU_UID, "好读团", 1, 0
            );
            // 好读服务
            newCmserviceList.add(cmservices);
            newCmserviceList.add(haoduService);
        }
        membersService.saveOrUpdateBatch(newMemberList);
        cmordersService.saveOrUpdateBatch(newCmorderList);
        cmservicesService.saveOrUpdateBatch(newCmserviceList);

        String msg = "";
        if (CollectionUtils.isNotEmpty(newMemberList))
            msg = "保存会员" + newMemberList.size() + "个";
        if (CollectionUtils.isNotEmpty(exMemberList)) {
            String exMemberStr = exMemberList.stream().collect(Collectors.joining(","));
            msg += "，重复会员:" + exMemberList.size() + "个，" + exMemberStr;
        }

        // 清空门店会员缓存
        redisService.setNullLike(RedisParam.STORE_MEMBERS + storeUid);

        return R.ok(msg);
    }


    @ApiOperation(value = "1-10店正价会员不含到期未续费（人事）")
    @GetMapping(value = "/exportNewMember", produces = "application/vnd.ms-excel;charset=UTF-8")
    public void exportNewMember(
            HttpServletResponse response
    ) throws Exception {
        String today = DateUtil.getNowDateStr();
        List<Cmservices> cmservicesList = cmservicesService.listByStoreUidInAndEndDateAndLeftLesson(storeUidList, today);

        if (CollectionUtils.isEmpty(cmservicesList))
            throw new DescribeException("未查询到正价服务数据");

        Set<String> memberUidList = new HashSet<>();
        Set<String> orderCodeList = new HashSet<>();

        for (Cmservices cmservices : cmservicesList) {
            memberUidList.add(cmservices.getMemberUid());
            orderCodeList.add(cmservices.getOrderCode());
        }

        List<Members> membersList = membersService.listByUidInOrderByStoreUid(new ArrayList<>(memberUidList));
        if (CollectionUtils.isEmpty(membersList))
            throw new DescribeException("未查询到会员数据");

        List<CmorderDto> orderList = cmordersService.dotListByOrderCodeIn(new ArrayList<>(orderCodeList));
        if (CollectionUtils.isEmpty(membersList))
            throw new DescribeException("未查询到会员的订单数据");

        Map<String, List<Cmservices>> serviceMap = cmservicesList.stream().collect(Collectors.groupingBy(Cmservices::getMemberUid));

        Map<String, CmorderDto> orderMap = orderList.stream().collect(Collectors.toMap(CmorderDto::getOrderCode, Function.identity()));

        // 表格头部列的数据
        List<List<String>> headList = new ArrayList<>();
        // 表格第一列默认是门店名称
        headList.add(Collections.singletonList("门店名称"));
        headList.add(Collections.singletonList("会员名称"));
        headList.add(Collections.singletonList("报名日期"));
        headList.add(Collections.singletonList("报名课程"));
        headList.add(Collections.singletonList("服务日期"));
        // 表格内的数据
        List<List<Object>> dataList = new ArrayList<>();

        for (Members members : membersList) {
            List<Cmservices> cmservices = serviceMap.get(members.getUid());
            for (int i = 0; i < cmservices.size(); i++) {
                List<Object> data = new ArrayList<>();
                Cmservices service = cmservices.get(i);
                // 门店名称
                data.add(members.getStoreName());
                // 会员名称
                data.add(members.getMemberName());
                // 报名日期
                CmorderDto cmorderDto = orderMap.get(service.getOrderCode());
                if (cmorderDto != null && cmorderDto.getOrderDate() != null)
                    data.add(DateUtil.getDefaultTime2DateStr(cmorderDto.getOrderDate()));

                data.add(CmorderUtil.getProductName(service));

                if (service.getBeginDate() != null && service.getEndDate() != null) {
                    String beginDate = DateUtil.getDefaultTime2DateStr(service.getBeginDate());
                    String endDate = DateUtil.getDefaultTime2DateStr(service.getEndDate());
                    data.add(beginDate + "-" + endDate);
                }

                dataList.add(data);
            }

            dataList.add(new ArrayList<>());
        }

        // 导出授权码
        String fileName = "1-10店正价会员不含到期未续费";
        EasyExcel.write(ExcelHandler.getOutputStream(fileName, response))
                // 这里放入动态头
                .head(headList).sheet("会员")
                // 当然这里数据也可以用 List<List<String>> 去传入
                .doWrite(dataList);
    }


    @ApiOperation(value = "按日期查询即将到期的会员（人事）")
    @GetMapping(value = "/exportOverdueMember", produces = "application/vnd.ms-excel;charset=UTF-8")
    public void exportOverdueMember(
            HttpServletResponse response,
            @ApiParam(value = "开始日期 yyyy-MM-dd") @RequestParam(value = "beginDate") String beginDate,
            @ApiParam(value = "结束日期 yyyy-MM-dd") @RequestParam(value = "endDate") String endDate
    ) throws Exception {
        List<Cmservices> cmservicesList = cmservicesService.overdueMemberList(storeUidList, beginDate, endDate);

        if (CollectionUtils.isEmpty(cmservicesList))
            throw new DescribeException("未查询到即将到期的服务");

        Set<String> memberUidList = new HashSet<>();
        Set<String> orderCodeList = new HashSet<>();

        for (Cmservices cmservices : cmservicesList) {
            memberUidList.add(cmservices.getMemberUid());
            orderCodeList.add(cmservices.getOrderCode());
        }

        List<Members> membersList = membersService.listByUidInOrderByStoreUid(new ArrayList<>(memberUidList));
        if (CollectionUtils.isEmpty(membersList))
            throw new DescribeException("未查询到会员数据");

        List<CmorderDto> orderList = cmordersService.dotListByOrderCodeIn(new ArrayList<>(orderCodeList));
        if (CollectionUtils.isEmpty(membersList))
            throw new DescribeException("未查询到会员的订单数据");
        List<CmservicesDto> serviceList = cmservicesService.dtoListByOrderCodes(null, new ArrayList<>(orderCodeList));

        Map<String, List<CmservicesDto>> serviceMap = serviceList.stream().collect(Collectors.groupingBy(CmservicesDto::getMemberUid, LinkedHashMap::new, Collectors.toList()));

        Map<String, CmorderDto> orderMap = orderList.stream().collect(Collectors.toMap(CmorderDto::getOrderCode, Function.identity()));

        // 表格头部列的数据
        List<List<String>> headList = new ArrayList<>();
        // 表格第一列默认是门店名称
        headList.add(Collections.singletonList("门店名称"));
        headList.add(Collections.singletonList("会员名称"));
        headList.add(Collections.singletonList("报名日期"));
        headList.add(Collections.singletonList("收入类型"));
        headList.add(Collections.singletonList("是否赠送"));
        headList.add(Collections.singletonList("服务名称"));
        headList.add(Collections.singletonList("服务状态"));
        headList.add(Collections.singletonList("服务日期"));
        headList.add(Collections.singletonList("剩余次数"));
        // 表格内的数据
        List<List<Object>> dataList = new ArrayList<>();

        for (Members members : membersList) {
            List<CmservicesDto> cmservices = serviceMap.get(members.getUid());
            for (int i = 0; i < cmservices.size(); i++) {
                List<Object> data = new ArrayList<>();
                CmservicesDto service = cmservices.get(i);
                // 门店名称
                data.add(members.getStoreName());
                // 会员名称
                data.add(members.getMemberName());
                // 报名日期
                CmorderDto cmorderDto = orderMap.get(service.getOrderCode());
                if (cmorderDto != null && cmorderDto.getOrderDate() != null)
                    data.add(DateUtil.getDefaultTime2DateStr(cmorderDto.getOrderDate()));
                else
                    data.add("");

                if (StringUtils.isNotBlank(cmorderDto.getOrderType()))
                    data.add(EnumType.OrderType.getName(cmorderDto.getOrderType()));
                else
                    data.add("");

                if (service.getIsGift() != null && service.getIsGift().equals(0))
                    data.add("非赠送");
                else
                    data.add("赠送");

                data.add(CmorderUtil.getProductName(service));
                data.add(service.getStatusName());

                if (service.getBeginDate() != null && service.getEndDate() != null) {
                    String bd = DateUtil.getDefaultTime2DateStr(service.getBeginDate());
                    String ed = DateUtil.getDefaultTime2DateStr(service.getEndDate());
                    data.add(bd + "-" + ed);
                } else
                    data.add("");

                if (CmorderUtil.isConsumeLesson(service.getLessonStatus(), service.getFreeStatus())) {
                    // 可排活动的服务
                    int leftLessonNum = NepUtil.nullToZero(service.getLeftLessons());
                    data.add(leftLessonNum);
                }

                dataList.add(data);
            }

            dataList.add(new ArrayList<>());
        }

        // 导出授权码
        String fileName = "查询即将到期的会员" + beginDate + "-" + endDate;
        EasyExcel.write(ExcelHandler.getOutputStream(fileName, response))
                .head(headList)
                .sheet("sheet")
                .doWrite(dataList);
    }


    @ApiOperation(value = "导入会员和订单服务")
    @PostMapping(value = "/importMemberAndCmorderV2")
    public R<Object> importMemberAndCmorderV2(
            @ApiParam(value = "会员数据excel") @RequestPart(value = "file") MultipartFile file,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "数据来源") @RequestParam(value = "source") String source
    ) throws Exception {
        List<MemberAndCmorderVOV2> voList = ExcelHandler.importExcel(file, MemberAndCmorderVOV2.class, null);
        if (CollectionUtils.isEmpty(voList))
            return R.fail("不能导入空数据");

        Object store = UidUtil.getStore(storeUid);
        if (store instanceof String)
            return R.fail(store.toString());
        Stores stores = (Stores) store;
        String corpUid = stores.getCorpUid();
        Long storesId = stores.getId();
        String storeName = stores.getStoreName();

        Staff staff = staffService.getByUid(staffUid);
        if (staff == null)
            return R.fail("店员获取失败");
        String staffName = staff.getFullName();

        Set<String> mobNameList = new HashSet<>();
        Set<String> saleNameList = new HashSet<>();
        Set<String> projectNameList = new HashSet<>();
        // 添加书籍信息
        for (int i = 0; i < voList.size(); i++) {
            MemberAndCmorderVOV2 vo = voList.get(i);
            int row = i + 1;
            String mob = vo.getMob();
            if (StringUtils.isBlank(mob))
                return R.fail("请填写手机号, 第" + row + "行");
            if (mob.length() != 11)
                return R.fail("手机号格式错误, 第" + row + "行");

            String name = vo.getName();
            if (StringUtils.isBlank(name))
                return R.fail("请填写姓名, 第" + row + "行");
            if (name.length() > 100)
                return R.fail("姓名长度超过限制, 第" + row + "行");

            String grade = vo.getGrade();
            if (StringUtils.isBlank(grade))
                return R.fail("请填写年级, 第" + row + "行");

            String orderDate = vo.getOrderDate();
            if (StringUtils.isBlank(orderDate))
                return R.fail("请填写收款日期, 第" + row + "行");

            String saleName = vo.getSaleName();
            if (StringUtils.isBlank(saleName))
                return R.fail("请填写签单人, 第" + row + "行");

            String projectName = vo.getProjectName();
            if (StringUtils.isBlank(projectName))
                return R.fail("请填写服务详情, 第" + row + "行");

            mobNameList.add(mob + "-" + name);
            saleNameList.add(saleName);

            // 处理服务包
            String[] projectNames = StringUtils.split(projectName, "\\/");
            List<ProjectInfoDto> projectInfoDtoList = new ArrayList<>();
            for (String projectInfo : projectNames) {
                String[] split = StringUtils.split(projectInfo, "-");
                ProjectInfoDto projectInfoDto = new ProjectInfoDto();
                for (int j = 0; j < split.length; j++) {
                    String value = split[j];
                    if (j == 0) {
                        projectInfoDto.setProjectName(value);
                        projectNameList.add(value);
                    }
                    if (j == 1) {
                        projectInfoDto.setDay(value);
                    }
                    if (j == 2) {
                        projectInfoDto.setLesson(value);
                    }
                }
                projectInfoDtoList.add(projectInfoDto);
            }
            vo.setProjectInfoDtoList(projectInfoDtoList);
        }

        if (voList.size() != mobNameList.size())
            return R.fail("手机号和姓名重复了");

        List<String> corpUidList = storesService.corpUidBySelfAndConsortium();

        // 根据签单人姓名，获取签单人信息
        List<Staff> staffList = staffService.listByCorpUidAndSaleNameIn(corpUidList, saleNameList);
        if (CollectionUtils.isEmpty(staffList))
            return R.fail("未获取到签单人");
        if (saleNameList.size() != staffList.size()) {
            List<String> collect = staffList.stream().map(Staff::getFullName).collect(Collectors.toList());
            return R.fail("部分签单人获取失败" + collect);
        }
        Map<String, List<Staff>> staffMap = staffList.stream().collect(Collectors.groupingBy(Staff::getFullName));

        // 根据服务名称，获取服务信息
        List<StoreProjects> storeProjectList = storeProjectsService.listByProjectNameIn(projectNameList);
        if (CollectionUtils.isEmpty(storeProjectList))
            return R.fail("未获取到服务");
        if (projectNameList.size() != storeProjectList.size())
            return R.fail("部分服务获取失败");
        Map<String, StoreProjects> projectMap = storeProjectList.stream().collect(Collectors.toMap(StoreProjects::getProjectName, Function.identity()));

        Double orderAmount = 99d;
        String orderType = EnumType.OrderType.EXP.getType();

        List<String> exMemberList = new ArrayList<>();
        List<Members> newMemberList = new ArrayList<>();
        List<Cmorders> newCmorderList = new ArrayList<>();
        List<Cmservices> newCmserviceList = new ArrayList<>();
        for (MemberAndCmorderVOV2 vo : voList) {
            String memberUid = "";
            String memberName = "";
            Members exMember = membersService.haveCorpUidAndMobAndFullName(corpUid, vo.getMob(), vo.getName(), null);
            if (null != exMember) {
                // 已有会员账号
                exMemberList.add(vo.getMob() + "-" + vo.getName());

                memberUid = exMember.getUid();
                memberName = exMember.getMemberName();
            } else {
                // 创建会员
                memberUid = KitUtil.getUuid();
                Members member = MemberUtil.createMemberByImport(
                        corpUid, storeUid, storeName, storesId, memberUid, vo.getMob(), vo.getName(), vo.getGrade(),
                        source, staffUid, staffName
                );
                memberName = member.getMemberName();
                newMemberList.add(member);
            }

            String saleStaffUid = "";
            String saleStaffFullName = "";
            String saleStaffPriPhone = "";
            String saleStaffPubPhone = "";
            String saleStaffNickName = "";
            List<Staff> saleStaffList = staffMap.get(vo.getSaleName());
            if (CollectionUtils.isNotEmpty(saleStaffList)) {
                Staff saleStaff = saleStaffList.get(0);
                saleStaffUid = saleStaff.getUid();
                saleStaffFullName = saleStaff.getFullName();
                saleStaffPriPhone = saleStaff.getPriPhone();
                saleStaffPubPhone = saleStaff.getPubPhone();
                saleStaffNickName = saleStaff.getNickName();
            }

            Date orderDateValue = null;
            if (StringUtils.isNotBlank(vo.getOrderDate()))
                orderDateValue = DateUtil.parseDate(vo.getOrderDate());

            List<ProjectInfoDto> projectInfoDtoList = vo.getProjectInfoDtoList();
            int serviceNum = projectInfoDtoList.size();
            // 创建订单信息
            Cmorders cmorders = CmorderUtil.newCmorder(
                    null, corpUid, storeUid, storeName, staffUid, staffName, memberUid, memberName,
                    saleStaffUid, saleStaffFullName, saleStaffPriPhone, saleStaffPubPhone, saleStaffNickName,
                    null, orderType, orderAmount, orderDateValue,
                    "0", null, vo.getRemark(), null, serviceNum, source
            );
            newCmorderList.add(cmorders);

            // 创建会员服务
            for (ProjectInfoDto projectInfoDto : projectInfoDtoList) {
                // 创建服务信息
                String projectName = projectInfoDto.getProjectName();
                Integer day = StringUtils.isNotBlank(projectInfoDto.getDay()) ? Integer.parseInt(projectInfoDto.getDay()) : null;
                Integer lesson = StringUtils.isNotBlank(projectInfoDto.getLesson()) ? Integer.parseInt(projectInfoDto.getLesson()) : null;

                StoreProjects storeProject = projectMap.get(projectName);
                if (storeProject == null)
                    return R.fail("服务项目获取失败");

                Cmservices cmservices = CmorderUtil.newImportService(
                        corpUid, storeUid, storeName,
                        memberUid, memberName, staffUid, staffName,
                        cmorders.getOrderCode(), orderType, lesson, day, 0,
                        storeProject.getId(), storeProject.getUid(), projectName, storeProject.getLessonStatus(), storeProject.getFreeStatus()
                );
                newCmserviceList.add(cmservices);
            }
        }
        membersService.saveOrUpdateBatch(newMemberList);
        cmordersService.saveOrUpdateBatch(newCmorderList);
        cmservicesService.saveOrUpdateBatch(newCmserviceList);

        String msg = "";
        if (CollectionUtils.isNotEmpty(newMemberList))
            msg = "新建会员" + newMemberList.size() + "个";
        if (CollectionUtils.isNotEmpty(exMemberList)) {
            String exMemberStr = exMemberList.stream().collect(Collectors.joining(","));
            msg += "，老会员:" + exMemberList.size() + "个，" + exMemberStr;
        }

        // 清空门店会员缓存
        redisService.setNullLike(RedisParam.STORE_MEMBERS + storeUid);

        return R.ok(msg);
    }


//    @ApiOperation(value = "更新会员的最后跟进记录uid")
//    @PostMapping(value = "/updateLastFollowUid")
//    public R<Object> updateLastFollowUid(
//            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
//            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
//            @ApiParam(value = "id范围max") @RequestParam(value = "idMax") String idMax,
//            @ApiParam(value = "id范围min") @RequestParam(value = "idMin") String idMin
//    ) {
//        List<Members> members = membersService.listByIdBetween(idMax, idMin);
//        if (CollectionUtils.isEmpty(members))
//            return R.fail("未查询到会员");
//
//        int cnt = 0;
//        for (Members member : members) {
//            List<String> memberFollowList = memberFollowService.listByMemberUidAndFollowTime(member.getUid(), member.getFollowTime());
//            if (CollectionUtils.isNotEmpty(memberFollowList)) {
//                String followUid = memberFollowList.get(0);
//                boolean b = membersService.updateLastFollowUid(member.getUid(), followUid);
//                if (b) {
//                    cnt++;
//                }
//            }
//        }
//        String content = "查询的会员总数：" + members.size() + "，更新成功数量：" + cnt;
//        return R.ok(content);
//    }

}